﻿using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using SdmxMl.Helper;
using SdmxMl.Common;

namespace SdmxMl.Structure
{
    /// <summary>
    /// ReportingTaxonomyType groups data flows and/or metadata flows for the purposes
    /// of assembling "reports" made up of data from disparate sources. It is a
    /// maintainable object, and thus has a mandatory human-readable Name and optional
    /// Description containing a longer human-readable description. Annotations may be
    /// included. All of these fields may be provided in multiple, parallel languages.
    /// The id attribute assignes a unique ID to the Reporting Taxonomy, version provides
    /// a version number, uri contains a URL where the SDMX-ML expression of the Reporting
    /// taxonomy can be found, and must be included if the isExternalReference attribute
    /// has a value of true. The urn attribute holds the value of a valid SDMX Registry
    /// URN as per the SDMX Registry specification. The isExternalReference attribute,
    /// if set to true, indicates that the uri attribute points to an external location
    /// for the ReportingTaxonomy, with only the id, Name element, and version supplied
    /// in addition. The agencyID attribute holds the ID of the Reporting Taxonomies'
    /// maintenance agency. Also, if the Reporting Taxonomy is final, the isFinal
    /// attribute must`have a value of true - otherwise, it will be assumed to be non-final.
    /// (All production versions must be made final - that is, unchangeable without versioning.)
    /// The sub-element Category may be used to group dataflows and metadataflows into useful
    /// sub-packages. DataflowRef and MetadataFlowRef are references to the flows which make up
    /// the reporting taxonomy at the top level. The validFrom and validTo attributes provide
    /// inclusive dates for providing supplemental validity information about the version.
    /// </summary>
    public class ReportingTaxonomyType: Artefact
    {
        #region Internal Members

        private DataFlowrefList _dataFlowList;
        private MetaDataFlowrefList _metaDataFlowList;
        private CategoryList _categoryList;

        #endregion

        #region Properties
        public override ArtefactRefTypedList ArtefactRefList
        {
            get 
            {
                ArtefactRefTypedList list = new ArtefactRefTypedList();

                return list;
            }
        }

        public DataFlowrefList DataFlowRefList
        {
            get { return _dataFlowList; }
            set { _dataFlowList = value; }
        }

        public MetaDataFlowrefList MetaDataFlowRefList
        {
            get { return _metaDataFlowList; }
            set { _metaDataFlowList = value; }
        }

        public CategoryList CategoryList
        {
            get { return _categoryList; }
        }
       
        #endregion //Properties

        #region Constructors
        
        private void Init()
        {
            _dataFlowList = new DataFlowrefList();
            _metaDataFlowList = new MetaDataFlowrefList();
            _categoryList = new CategoryList(null);
        }


        public ReportingTaxonomyType()
        {
            Init();
        }

        public ReportingTaxonomyType(XmlNode nodeArtefact, SdmxNamespaceManager nsmgr) 
            : base(nodeArtefact, nsmgr)
        {
            Init();

            string query = "./structure:Category";
            XmlNodeList nodeList = nodeArtefact.SelectNodes(query, nsmgr);
            if (nodeList.Count > 0)
            {
                foreach (XmlNode nd in nodeList)
                {
                    Category c = new Category(CategoryList, null, nd, nsmgr);
                    CategoryList.Add(c);
                }
            }

            XmlNodeList nodeFlowList = nodeArtefact.SelectNodes("./structure:MetadataflowRef", nsmgr);
            foreach (XmlNode nd in nodeFlowList)
            {
                MetaDataFlowRef mf = new MetaDataFlowRef(nd, nsmgr);
                _metaDataFlowList.Add(mf);
            }

            nodeFlowList = nodeArtefact.SelectNodes("./structure:DataflowRef", nsmgr);
            foreach (XmlNode nd in nodeFlowList)
            {
                DataFlowRef df = new DataFlowRef(nd, nsmgr);
                _dataFlowList.Add(df);
            }

        }

        #endregion // Constructors

        #region XML serialize

        public override void WriteXmlInsider(XmlTextWriter xw)
        {
            string prefix = "structure";

            // All Flow ref
            foreach (DataFlowRef df in _dataFlowList)
                df.WriteXml(xw, prefix, "DataflowRef");
            foreach (MetaDataFlowRef mdf in _metaDataFlowList)
                mdf.WriteXml(xw, prefix, "MetadataflowRef");

            foreach (Category cat in _categoryList)
                cat.WriteXml(xw, prefix, "Category");
        }

        #endregion

        #region Tree

        public override TreeNode FillNode(TreeNode parentNode)
        {
            TreeNode t = base.FillNode(parentNode);
            TreeNode tc = new TreeNode(_categoryList.ToString(), 1, 1);
            tc.Tag = _categoryList;
            t.Nodes.Add(tc);
            foreach (Category c in _categoryList)
                c.FillNode(tc);

            return t;
        }

        #endregion // Tree

        #region Artefact Type

        public override Manager.SdmxArtefactType ArType
        {
            get { return Manager.SdmxArtefactType.ReportingTaxonomies; }
        }

        #endregion
    }
}
